//
//  InfinitelyScrollingView.m
//  TRoad2
//
//  Created by ZhangYanhua on 14/11/13.
//  Copyright (c) 2014年 Mach. All rights reserved.
//

#import "CenterInfinitelyScrollingView.h"
#import "QWKitConfig.h"

#define CELL_COUNT_MULTIPER             1002
#define AUTO_SCROLL_INTERVAL            5.0f
#define InifiniteScrollOnePixelWidth    (1.0f/[UIScreen mainScreen].scale)

@interface CenterInfinitelyScrollingView() {
}


@end

@implementation CenterInfinitelyScrollingView

- (void)scrollToNextPage:(NSTimer *)timer
{
    if (!self.collectionView.isDragging && !self.collectionView.isTracking) {
        NSIndexPath *indexPath = [self.collectionView indexPathForItemAtPoint:CGPointMake(self.collectionView.contentOffset.x + self.collectionView.frame.size.width / 2.0f, 1.0f)];
        
        if (indexPath == nil) {
            NSArray *array = [self.collectionView indexPathsForVisibleItems];
            indexPath = [array firstObject];
        }
        
        if (indexPath) {
            NSInteger index = (indexPath.row + 1);
            NSIndexPath *newIndexPath = [NSIndexPath indexPathForItem:index inSection:0];

            [self.collectionView scrollToItemAtIndexPath:newIndexPath
                                        atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally
                                                animated:YES];
        }
    }
}

-(void)setupDataForCollectionView {
    // Create the original set of data
    self.collectionView.scrollEnabled = ([self.itemArray count] > 1);

    [self.collectionView reloadData];

    if (self.itemArray.count > 1) {
        NSInteger numberOfItem = self.itemArray.count;
        NSInteger centerIndex = (CELL_COUNT_MULTIPER / 2 * numberOfItem);
        
        float itemWidth = [self.collectionViewLayout itemSize].width + self.collectionViewLayout.minimumInteritemSpacing;
        float itemHeight = [self.collectionViewLayout itemSize].height;
        
        float itemMargin = (kQWKitScreenWidth - itemWidth) / 2.0f;
        
        [self.collectionView setContentSize:CGSizeMake(itemWidth *  CELL_COUNT_MULTIPER * numberOfItem, itemHeight)];
        [self.collectionView setContentOffset:CGPointMake(centerIndex * itemWidth-itemMargin, 0.0f) animated:NO];

        [_scrollTimer invalidate];
        _scrollTimer = nil;

        CGFloat delayInSeconds = 0.5 * (_currentIndex % 5);
        __weak CenterInfinitelyScrollingView *weakSelf = self;
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            [weakSelf startTimer];
        });
    } else {
        if (self.itemArray.count == 1) {
            self.collectionView.contentSize = self.collectionViewLayout.collectionViewContentSize;

            [self.collectionView setContentOffset:CGPointMake((self.collectionView.contentSize.width-kQWKitScreenWidth)/2, 0.0f) animated:NO];
        }

        [_scrollTimer invalidate];
        _scrollTimer = nil;
    }
}

- (void)setDisableAutoScroll:(BOOL)disableAutoScroll
{
    _disableAutoScroll = disableAutoScroll;

    if (disableAutoScroll) {
        [_scrollTimer invalidate];
        _scrollTimer = nil;
    }
}

- (void)startTimer
{
    if (_scrollTimer || _disableAutoScroll) {
        return;
    }

    _scrollTimer = [NSTimer scheduledTimerWithTimeInterval:AUTO_SCROLL_INTERVAL
                                                    target:self
                                                  selector:@selector(scrollToNextPage:)
                                                  userInfo:nil
                                                   repeats:YES];
}

- (void)dealloc
{
}

- (id)initWithFrame:(CGRect)aFrame ItemArray:(NSArray *)itemArray
{
    if (self = [super initWithFrame:aFrame]) {
        _itemArray = itemArray;
        
        [self commonSetup];
        [self setupDataForCollectionView];
    }
    return self;
}

- (id)initWithCoder:(NSCoder *)aDecoder
{
    if (self = [super initWithCoder:aDecoder]) {
        _itemArray = nil;
        
        [self commonSetup];
        [self setupDataForCollectionView];
    }
    
    return self;
}

- (void)setItemArray:(NSArray *)itemArray
{
    _itemArray = itemArray;

    [self setupDataForCollectionView];
}

- (void)commonSetup
{
    self.collectionViewLayout = [[CenterPagingFlowCollectionLayout alloc] init];
    [self.collectionViewLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
    [self.collectionViewLayout setMinimumInteritemSpacing:5.0f];
    [self.collectionViewLayout setSectionInset:UIEdgeInsetsZero];
    
    self.collectionView = [[UICollectionView alloc] initWithFrame:self.bounds
                                             collectionViewLayout:self.collectionViewLayout];
    [self.collectionView setAutoresizingMask:UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth];
    [self.collectionView setDataSource:self];
    [self.collectionView setDelegate:self];
    [self.collectionView setShowsHorizontalScrollIndicator:NO];
    [self.collectionView setShowsVerticalScrollIndicator:NO];
    [self.collectionView setScrollsToTop:NO];
    
    [self.collectionView registerClass:[UICollectionViewCell class]
            forCellWithReuseIdentifier:@"CenterInfinitelyScrollingEmptyCell"];
    
    self.collectionView.decelerationRate = UIScrollViewDecelerationRateFast;

    [self addSubview:self.collectionView];
}

#pragma mark - UICollectionView Datasource
- (NSInteger)collectionView:(UICollectionView *)view numberOfItemsInSection:(NSInteger)section {
    if ([self.itemArray count] == 1) {
        return 3;
    } else if ([self.itemArray count] <= 0) {
        return 0;
    }

    return CELL_COUNT_MULTIPER * self.itemArray.count;
}

- (NSInteger)numberOfSectionsInCollectionView: (UICollectionView *)collectionView {
    return 1;
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    if ([self.delegate respondsToSelector:@selector(collectionView:cellForItemAtIndexPath:withItem:withObject:)]) {
        if ([self.itemArray count] == 1 && (indexPath.row == 0 || indexPath.row == 2)) {
            UICollectionViewCell *cell = [cv dequeueReusableCellWithReuseIdentifier:@"CenterInfinitelyScrollingEmptyCell"
                                                                       forIndexPath:indexPath];
            cell.backgroundColor = [UIColor whiteColor];
            cell.contentView.layer.borderColor = V4_SeparatorLineColor.CGColor;
            cell.contentView.layer.borderWidth = InifiniteScrollOnePixelWidth;
            
            return cell;
        }

        return [self.delegate collectionView:cv
                      cellForItemAtIndexPath:indexPath
                                    withItem:self.itemArray[indexPath.row % self.itemArray.count]
                                  withObject:self.items];
    }

    return nil;
}

#pragma mark - UICollectionViewDelegate

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
    if (!decelerate) {
        if (self.itemArray.count <= 1) {
            return;
        }

        [_scrollTimer setFireDate:[NSDate dateWithTimeIntervalSinceNow:AUTO_SCROLL_INTERVAL]];
        
        // Calculate where the collection view should be at the right-hand end item
        float itemWidth = [self.collectionViewLayout itemSize].width + self.collectionViewLayout.minimumInteritemSpacing;
        float contentOffsetWhenFullyScrolledRight = itemWidth * (2 * self.itemArray.count * CELL_COUNT_MULTIPER / 3);
        float contentOffsetWhenFullyScrolledLeft  = itemWidth * (self.itemArray.count * CELL_COUNT_MULTIPER / 3);
        
        NSIndexPath *newIndexPath = nil;
        
        if (scrollView.contentOffset.x + __FLT_EPSILON__ >= contentOffsetWhenFullyScrolledRight) {
            
            // user is scrolling to the right from the last item to the 'fake' item 1.
            // reposition offset to show the 'real' item 1 at the left-hand end of the collection view
            newIndexPath = [NSIndexPath indexPathForItem:(self.itemArray.count * CELL_COUNT_MULTIPER / 3) inSection:0];
            
            [self.collectionView scrollToItemAtIndexPath:newIndexPath atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:NO];
            
        } else if (scrollView.contentOffset.x <= contentOffsetWhenFullyScrolledLeft + __FLT_EPSILON__)  {
            
            // user is scrolling to the left from the first item to the fake 'item N'.
            // reposition offset to show the 'real' item N at the right end end of the collection view
            
            newIndexPath = [NSIndexPath indexPathForItem:(2 * self.itemArray.count * CELL_COUNT_MULTIPER / 3 - 1) inSection:0];
            
            [self.collectionView scrollToItemAtIndexPath:newIndexPath atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:NO];
            
        }
        
        if ([self.delegate respondsToSelector:@selector(collectionView:displayItemAtIndex:)]) {
            NSInteger index = (scrollView.contentOffset.x + itemWidth / 2.0f) / itemWidth;
            index = self.itemArray.count ? index % self.itemArray.count : 0;
            
            [self.delegate collectionView:self.collectionView displayItemAtIndex:index];
        }
    }
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    if (self.itemArray.count <= 1) {
        return;
    }

    [_scrollTimer setFireDate:[NSDate dateWithTimeIntervalSinceNow:AUTO_SCROLL_INTERVAL]];
    
    // Calculate where the collection view should be at the right-hand end item
    float itemWidth = [self.collectionViewLayout itemSize].width + self.collectionViewLayout.minimumInteritemSpacing;
    float contentOffsetWhenFullyScrolledRight = itemWidth * (2 * self.itemArray.count * CELL_COUNT_MULTIPER / 3);
    float contentOffsetWhenFullyScrolledLeft  = itemWidth * (self.itemArray.count * CELL_COUNT_MULTIPER / 3);
    
    if (scrollView.contentOffset.x + __FLT_EPSILON__ >= contentOffsetWhenFullyScrolledRight) {

        // user is scrolling to the right from the last item to the 'fake' item 1.
        // reposition offset to show the 'real' item 1 at the left-hand end of the collection view
        NSIndexPath *newIndexPath = [NSIndexPath indexPathForItem:(self.itemArray.count * CELL_COUNT_MULTIPER / 3) inSection:0];
        
        [self.collectionView scrollToItemAtIndexPath:newIndexPath atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:NO];
        
    } else if (scrollView.contentOffset.x <= contentOffsetWhenFullyScrolledLeft + __FLT_EPSILON__)  {
        
        // user is scrolling to the left from the first item to the fake 'item N'.
        // reposition offset to show the 'real' item N at the right end end of the collection view
        
        NSIndexPath *newIndexPath = [NSIndexPath indexPathForItem:(2 * self.itemArray.count * CELL_COUNT_MULTIPER / 3 - 1) inSection:0];
        
        [self.collectionView scrollToItemAtIndexPath:newIndexPath atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:NO];
        
    }

    if ([self.delegate respondsToSelector:@selector(collectionView:displayItemAtIndex:)]) {
        NSInteger index = (scrollView.contentOffset.x + itemWidth / 2.0f) / itemWidth;
        index = self.itemArray.count ? index % self.itemArray.count : 0;
        
        [self.delegate collectionView:self.collectionView displayItemAtIndex:index];
    }
    
}

- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView
{
    if (self.itemArray.count <= 1) {
        return;
    }

    if ([self.delegate respondsToSelector:@selector(collectionView:displayItemAtIndex:)]) {
        float itemWidth = [self.collectionViewLayout itemSize].width + self.collectionViewLayout.minimumInteritemSpacing;

        NSInteger index = (scrollView.contentOffset.x + itemWidth / 2.0f) / itemWidth;
        index = self.itemArray.count ? index % self.itemArray.count : 0;

        [self.delegate collectionView:self.collectionView displayItemAtIndex:index];
    }
    
    if (!scrollView.isDragging && !scrollView.isTracking) {
        // Calculate where the collection view should be at the right-hand end item
        float itemWidth = [self.collectionViewLayout itemSize].width + self.collectionViewLayout.minimumInteritemSpacing;
        float contentOffsetWhenFullyScrolledRight = itemWidth * (2 * self.itemArray.count * CELL_COUNT_MULTIPER / 3);
        float contentOffsetWhenFullyScrolledLeft  = itemWidth * (self.itemArray.count * CELL_COUNT_MULTIPER / 3);
        
        if (scrollView.contentOffset.x + __FLT_EPSILON__ >= contentOffsetWhenFullyScrolledRight) {
            
            // user is scrolling to the right from the last item to the 'fake' item 1.
            // reposition offset to show the 'real' item 1 at the left-hand end of the collection view
            NSIndexPath *newIndexPath = [NSIndexPath indexPathForItem:(self.itemArray.count * CELL_COUNT_MULTIPER / 3) inSection:0];
            
            [self.collectionView scrollToItemAtIndexPath:newIndexPath atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:NO];
            
        } else if (scrollView.contentOffset.x <= contentOffsetWhenFullyScrolledLeft + __FLT_EPSILON__)  {
            
            // user is scrolling to the left from the first item to the fake 'item N'.
            // reposition offset to show the 'real' item N at the right end end of the collection view
            
            NSIndexPath *newIndexPath = [NSIndexPath indexPathForItem:(2 * self.itemArray.count * CELL_COUNT_MULTIPER / 3 - 1) inSection:0];
            
            [self.collectionView scrollToItemAtIndexPath:newIndexPath atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:NO];
            
        }
    }
}

@end
